//
//  AppController.m
//  Pitfalls01
//
//  Created by codie on 8/4/09.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//

#import "AppController.h"
#import "ContentLoader.h"

@implementation AppController

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
	// let's set a name to our main thread so we can 
	// distinguish it later from the secondary thread
	[[NSThread currentThread] setName:@"Main thread"];
}


- (IBAction)loadContent:(id)sender {
	
	// let's begin demonstrating this pitfall
	
	// this class will spawn a secondary thread
	ContentLoader *cl = [[ContentLoader alloc] init];
	
	// let's observe this class via the notification center
	// let's register for two notifications
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:@"contentLoaded" object:cl];
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:@"anotherNotification" object:cl];
	
	[cl start];
}

- (void) handleNotification:(NSNotification *)notification {
	// we received the notification, let's see 
	// who is the active thread
	NSLog(@"thread name: %@", [[NSThread currentThread] name]);
	// as expected, the active thread is the secondary thread
	
	// now when we execute the following code
	// we are going to have a "WebKit Threading Violation" error
	// because webView's loadData requires to be run on a main thread
	[[webView mainFrame] loadData:nil MIMEType:nil textEncodingName:nil baseURL:nil];
														
}


- (IBAction)betterApproachClicked:(id)sender {
	// let's begin demonstrating a better approach
	// to avoid this pitfall
	
	ContentLoader *cl = [[ContentLoader alloc] init];
	
	// this time we pass nil to the name parameter
	// so we could observe all notifications coming
	// from ContentLoader
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleAllNotifications:) name:nil object:cl];
	[cl start];
}

- (void) handleAllNotifications:(NSNotification *)notification {
	
	NSLog(@"thread name: %@", [[NSThread currentThread] name]);
	// yes, this could still be from the secondary thread
	// but it doesn't matter now

	// now we check which notification was sent
	if ([notification name] == @"contentLoaded") {
		[self performSelectorOnMainThread:@selector(handleContentLoadNotification:) withObject:[notification object] waitUntilDone:NO];
		// now we are guaranteed that this method
		// will run on a main thread
		// we also passed on the notification sender/object
		// which is the ContentLoader class
	}
	else if ([notification name] == @"anotherNotification") {
		// or you could decide to run a selector
		// on a specific thread by calling
		// performSelector:(SEL)aSelector onThread:(NSThread *)
	}
	else {
		// or you could simply ignore the notification
	}
}
		 
- (void) handleContentLoadNotification: (id) object {
	NSLog(@"thread name: %@", [[NSThread currentThread] name]);
	// yup, we are running on a main thread
	ContentLoader *cl = (ContentLoader *) object;
	
	// let's get the dummy content.
	 NSString *strSource = [cl dummyContent];

	// finally, we can load the content to our webview
	// withour threading violations this time
	[[webView mainFrame] loadHTMLString:strSource baseURL:nil];
}
			
			
													
@end
